package com.ruoyi.framework.aspectj;

import com.ruoyi.common.annotation.NoRepeatSubmit;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class NoRepeatSubmitAspect {

    private static final Logger logger = LoggerFactory.getLogger(NoRepeatSubmitAspect.class);

    @Resource
    private RedisCache redisCache;

    /**
     * 横切点
     */
    @Pointcut("@annotation(noRepeatSubmit)")
    public void repeatPoint(NoRepeatSubmit noRepeatSubmit) {
    }

    /**
     * 接收请求，并记录数据
     */
    @Around(value = "repeatPoint(noRepeatSubmit)")
    public Object doBefore(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) {
        // 获取IP地址
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        // 获取请求地址
        String requestURI = ServletUtils.getRequest().getRequestURI();
        String name = noRepeatSubmit.name();
        String key = ip + requestURI + ":" + name;
        int seconds = noRepeatSubmit.seconds();
        if (redisCache.hasKey(key)) {
            return AjaxResult.error("操作过于频繁，请稍后重试");
        }
        try {
            Object proceed = joinPoint.proceed();
            return proceed;
        } catch (Throwable throwable) {
            logger.error("运行业务代码出错", throwable);
            throw new RuntimeException(throwable.getMessage());
        } finally {
            redisCache.setCacheObject(key, name, seconds, TimeUnit.SECONDS);
        }
    }
}
